﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using System.ComponentModel;
using System.Windows.Forms;

namespace FontManager
{
    /// <summary>
    /// font character class contains the information specific for each character;
    /// Each character in here represent a character in font file.
    /// </summary>
    public class FontCharacter : System.ComponentModel.INotifyPropertyChanged
    {
        #region variables
        /// <summary>
        /// Name is the character value of this character
        /// </summary>
        private string _characterName = "";    
        /// <summary>
        /// Uri from where the image will be loaded
        /// </summary>
        private string _characterImageUri = "";     
        /// <summary>
        /// anchor points are the coordinates which will be taken when drawing the object.
        /// Anchor point will be the point which will be placed on the base line when drawing.
        /// </summary>     
        private PointF _characterAnchorPoint;   
        /// <summary>
        /// The width of the character. This is not the full width. 
        /// This width starts from AnchorPoint.X, not from the beginning of the image.
        /// </summary>
        private float _characterWidth = 0;                    
        #endregion

        /// <summary>
        /// Properties for above methods with some additional for easier access (like anchor point X.y)
        /// NOTICE: _characterWidth = (float)Math.Round(value, 3) - to control width length after the '.'
        /// </summary>
        #region properties
        [Category("Character Additional info"), DescriptionAttribute("The original height of a character")]
        public float CropedHeight { get; set; }

        [Category("Character Additional info"), DescriptionAttribute("The height of actual png file storing this character")]
        public float Height { get; set; }

        [Category("Character Additional info"), DescriptionAttribute("png file storing this represented character")]
        public string Image { get { return _characterImageUri; } set { _characterImageUri = value; } }

        [Category("Character XML data"), DescriptionAttribute("The _name of the character (in HEX value) which corresponds to file _name of png")]
        public string Name { get { return _characterName; } set { _characterName = value; } }

        [Category("Character XML data"), DescriptionAttribute("The anchor point which is taken when character is drawed")]
        public PointF AnchorPoint
        {
            get { return _characterAnchorPoint; }
            set
            {
                _characterAnchorPoint= value;
            }
        }

        [Category("Character XML data"), DescriptionAttribute("The anchor point X value which is taken when character is drawed")]
        public float AnchorPointX
        {
            get { return _characterAnchorPoint.X; }
            set
            {
                _characterAnchorPoint.X = value;
            }
        }

        [Category("Character XML data"), DescriptionAttribute("The anchor point Y value which is taken when character is drawed")]
        public float AnchorPointY
        {
            get { return _characterAnchorPoint.Y; }
            set
            {
                _characterAnchorPoint.Y = value;
            }
        }

        [Category("Character XML data"), DescriptionAttribute("The width of the character (anchor point the begining of drawing & Width shows the end). Full image is drawed, but after width part is not considered calculating location.")]
        public float Width
        {
            get { return _characterWidth; }
            set
            {
                _characterWidth = (float)Math.Round(value, 3);
                NotifyPropertyChanged("Space");
            }
        }
        #endregion

        #region constructors
        /// <summary>
        /// Empty one is used when want to create an empty object without any initial values
        /// </summary>
        public FontCharacter()
        { }

        /// <summary>
        /// for building characters from xml file,using when we know those values
        /// </summary>
        /// <param _name="HexName">character value of the char (_name without extensions)</param>
        /// <param _name="anchorX">X coordinate of anchor point</param>
        /// <param _name="anchorY">Y coordinate of anchor point</param>
        /// <param _name="width">the width of the character(from anchor X till this value)</param>
        public FontCharacter(string hexName, float anchorX, float anchorY, float width)
        {
            Name = hexName;
            AnchorPoint = new PointF(anchorX, anchorY);
            Width = width;
        }
        #endregion

        #region guess values
        /// <summary>
        /// guesses the values of character height based on its original values.
        /// cropedHeight is the height of the character when all the white space removed (from all directions)
        /// Height is the value of image height without any vertical croping done.
        /// </summary>
        public void GuessOnlyHeight()
        {
            try
            {
                CropedHeight = Helper.cropImage(_characterImageUri).Height;
                Height = (float)(Bitmap.FromFile(_characterImageUri).Height);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error occured in FontCharacter.GuessOnlyHeight(). \n" + ex.Message);
            }
        }

        /// <summary>
        /// Guesses values based on used Image.
        /// Guesses Height, Width, Name, Anchor point.
        /// Image disposed afterwords.
        /// </summary>
        public void GuessValues()
        {
            try
            {
                using (Image bmp = Bitmap.FromFile(_characterImageUri))
                {
                    CropedHeight = Helper.cropImage(_characterImageUri).Height;
                    Height = bmp.Height;
                    _characterWidth = bmp.Width;
                    _characterName = Path.GetFileNameWithoutExtension(_characterImageUri);

                    AnchorPointX = 0;
                    AnchorPointY = Height * 0.75f;
                    bmp.Dispose();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error occured in FontCharacter.GuessValues(). \n" + ex.Message);
            }
        }
        #endregion

        #region propertyChanged event
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// no longer has any purpose. was used for changes monitoring and updating xml file at runtime.
        /// </summary>
        /// <param name="imageUri"></param>
        private void NotifyPropertyChanged(string imageUri)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(imageUri));
        }
        #endregion
    }
}
